package edu.chalmers.platypus.view.gui;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.ImageIcon;
import javax.swing.Timer;

import edu.chalmers.platypus.util.ComBus;
import edu.chalmers.platypus.util.StateChanges;
import edu.chalmers.platypus.view.PlatypusGUI;

/**
 * Panel which shows two preview areas (ImagePreviewPanel). Used for showing the
 * user the original image, and the image with filters applied.
 * 
 */
public class PreviewPanel extends javax.swing.JPanel implements
	PropertyChangeListener, ActionListener {
    /**
     * Timer for not allowing requests for new preview images too often when
     * resizing
     */
    private Timer resizeTimer;

    /** Constructor */
    public PreviewPanel() {
	initComponents();
	resizeTimer = new Timer(500, this);
	ComBus.subscribe(this);
    }

    /**
     * Creates new thread for getting the original of the picture set as preview
     */
    public void setPreviewOriginal() {
	Thread t = new Thread(new Runnable() {
	    @Override
	    public void run() {
		ImageIcon i = PlatypusGUI.getInstance().getPreviewOriginal(
			originalPreviewPanel.getWidth() - 2,
			originalPreviewPanel.getHeight() - 2);
		originalPreviewPanel.setImage(i);
	    }
	});
	t.start();
    }

    /**
     * Creates new thread for getting preview image with currently added filter
     * applied.
     */
    public void setPreviewFiltered() {
	Thread t = new Thread(new Runnable() {
	    @Override
	    public void run() {
		ImageIcon i = PlatypusGUI.getInstance().getPreviewFiltered(
			filteredPreviewPanel.getWidth() - 2,
			filteredPreviewPanel.getHeight() - 2);
		filteredPreviewPanel.setImage(i);
	    }
	});
	t.start();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed"
    // desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

	previewSplitPane = new javax.swing.JSplitPane();
	originalPreviewContainerPanel = new javax.swing.JPanel();
	originalLabel = new javax.swing.JLabel();
	originalPreviewPanel = new edu.chalmers.platypus.view.gui.ImagePreviewPanel();
	filteredPreviewContainerPanel = new javax.swing.JPanel();
	filteredLabel = new javax.swing.JLabel();
	filteredPreviewPanel = new edu.chalmers.platypus.view.gui.ImagePreviewPanel();

	setName("Form"); // NOI18N

	previewSplitPane.setBorder(null);
	previewSplitPane.setDividerLocation(200);
	previewSplitPane.setDividerSize(0);
	previewSplitPane.setName("previewSplitPane"); // NOI18N
	previewSplitPane
		.addComponentListener(new java.awt.event.ComponentAdapter() {
		    public void componentResized(
			    java.awt.event.ComponentEvent evt) {
			previewSplitPaneComponentResized(evt);
		    }
		});

	originalPreviewContainerPanel.setName("originalPreviewContainerPanel"); // NOI18N

	originalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
	org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application
		.getInstance().getContext().getResourceMap(PreviewPanel.class);
	originalLabel.setText(resourceMap.getString("originalLabel.text")); // NOI18N
	originalLabel.setName("originalLabel"); // NOI18N

	originalPreviewPanel.setName("originalPreviewPanel"); // NOI18N
	originalPreviewPanel
		.addComponentListener(new java.awt.event.ComponentAdapter() {
		    public void componentResized(
			    java.awt.event.ComponentEvent evt) {
			originalPreviewPanelComponentResized(evt);
		    }
		});

	javax.swing.GroupLayout originalPreviewContainerPanelLayout = new javax.swing.GroupLayout(
		originalPreviewContainerPanel);
	originalPreviewContainerPanel
		.setLayout(originalPreviewContainerPanelLayout);
	originalPreviewContainerPanelLayout
		.setHorizontalGroup(originalPreviewContainerPanelLayout
			.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING)
			.addComponent(originalLabel,
				javax.swing.GroupLayout.DEFAULT_SIZE, 200,
				Short.MAX_VALUE)
			.addGroup(
				originalPreviewContainerPanelLayout
					.createSequentialGroup()
					.addGap(10, 10, 10)
					.addComponent(
						originalPreviewPanel,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						180, Short.MAX_VALUE)
					.addGap(10, 10, 10)));
	originalPreviewContainerPanelLayout
		.setVerticalGroup(originalPreviewContainerPanelLayout
			.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING)
			.addGroup(
				originalPreviewContainerPanelLayout
					.createSequentialGroup()
					.addComponent(
						originalLabel,
						javax.swing.GroupLayout.PREFERRED_SIZE,
						20,
						javax.swing.GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(
						javax.swing.LayoutStyle.ComponentPlacement.RELATED)
					.addComponent(
						originalPreviewPanel,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						108, Short.MAX_VALUE)
					.addContainerGap()));

	previewSplitPane.setLeftComponent(originalPreviewContainerPanel);

	filteredPreviewContainerPanel.setName("filteredPreviewContainerPanel"); // NOI18N

	filteredLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
	filteredLabel.setText(resourceMap.getString("filteredLabel.text")); // NOI18N
	filteredLabel.setName("filteredLabel"); // NOI18N

	filteredPreviewPanel.setName("filteredPreviewPanel"); // NOI18N
	filteredPreviewPanel
		.addComponentListener(new java.awt.event.ComponentAdapter() {
		    public void componentResized(
			    java.awt.event.ComponentEvent evt) {
			filteredPreviewPanelComponentResized(evt);
		    }
		});

	javax.swing.GroupLayout filteredPreviewContainerPanelLayout = new javax.swing.GroupLayout(
		filteredPreviewContainerPanel);
	filteredPreviewContainerPanel
		.setLayout(filteredPreviewContainerPanelLayout);
	filteredPreviewContainerPanelLayout
		.setHorizontalGroup(filteredPreviewContainerPanelLayout
			.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING)
			.addComponent(filteredLabel,
				javax.swing.GroupLayout.DEFAULT_SIZE, 251,
				Short.MAX_VALUE)
			.addGroup(
				filteredPreviewContainerPanelLayout
					.createSequentialGroup()
					.addGap(10, 10, 10)
					.addComponent(
						filteredPreviewPanel,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						231, Short.MAX_VALUE)
					.addGap(10, 10, 10)));
	filteredPreviewContainerPanelLayout
		.setVerticalGroup(filteredPreviewContainerPanelLayout
			.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING)
			.addGroup(
				filteredPreviewContainerPanelLayout
					.createSequentialGroup()
					.addComponent(
						filteredLabel,
						javax.swing.GroupLayout.PREFERRED_SIZE,
						20,
						javax.swing.GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(
						javax.swing.LayoutStyle.ComponentPlacement.RELATED)
					.addComponent(
						filteredPreviewPanel,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						108, Short.MAX_VALUE)
					.addContainerGap()));

	previewSplitPane.setRightComponent(filteredPreviewContainerPanel);

	javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
	this.setLayout(layout);
	layout.setHorizontalGroup(layout.createParallelGroup(
		javax.swing.GroupLayout.Alignment.LEADING).addComponent(
		previewSplitPane, javax.swing.GroupLayout.Alignment.TRAILING,
		javax.swing.GroupLayout.DEFAULT_SIZE, 451, Short.MAX_VALUE));
	layout.setVerticalGroup(layout.createParallelGroup(
		javax.swing.GroupLayout.Alignment.LEADING).addGroup(
		layout.createSequentialGroup()
			.addComponent(previewSplitPane,
				javax.swing.GroupLayout.DEFAULT_SIZE, 145,
				Short.MAX_VALUE).addContainerGap()));
    }// </editor-fold>//GEN-END:initComponents

    private void previewSplitPaneComponentResized(
	    java.awt.event.ComponentEvent evt) {// GEN-FIRST:event_previewSplitPaneComponentResized
	previewSplitPane.setDividerLocation(0.5);
    }// GEN-LAST:event_previewSplitPaneComponentResized

    private void originalPreviewPanelComponentResized(
	    java.awt.event.ComponentEvent evt) {// GEN-FIRST:event_originalPreviewPanelComponentResized
	resizeTimer.start();
    }// GEN-LAST:event_originalPreviewPanelComponentResized

    private void filteredPreviewPanelComponentResized(
	    java.awt.event.ComponentEvent evt) {// GEN-FIRST:event_filteredPreviewPanelComponentResized
	resizeTimer.start();
    }// GEN-LAST:event_filteredPreviewPanelComponentResized

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel filteredLabel;
    private javax.swing.JPanel filteredPreviewContainerPanel;
    private edu.chalmers.platypus.view.gui.ImagePreviewPanel filteredPreviewPanel;
    private javax.swing.JLabel originalLabel;
    private javax.swing.JPanel originalPreviewContainerPanel;
    private edu.chalmers.platypus.view.gui.ImagePreviewPanel originalPreviewPanel;
    private javax.swing.JSplitPane previewSplitPane;

    // End of variables declaration//GEN-END:variables

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
	String change = evt.getPropertyName();
	if (change.equals(StateChanges.NEW_PREVIEW_IMAGE.toString())) {
	    // New preview image set, shows new original and filtered
	    setPreviewOriginal();
	    setPreviewFiltered();
	} else if (change.equals(StateChanges.PREVIEW_IMAGE_UPDATED.toString())) {
	    // Preview image updated, i.e. filter settings changed. Update
	    // image.
	    setPreviewFiltered();
	} else if (change.equals(StateChanges.FILTER_REMOVED_FROM_BATCH
		.toString())) {
	    // Filter removed from batch. Updates filtered image accordingly.
	    setPreviewFiltered();
	} else if (change.equals(StateChanges.NEW_FILTER_ADDED_TO_BATCH
		.toString())) {
	    // Filter added to batch. Updates filtered image accordingly.
	    setPreviewFiltered();
	}
    }

    @Override
    public void actionPerformed(ActionEvent e) {
	// Stops timer, gets new preview images in the correct size
	resizeTimer.stop();
	originalPreviewPanel.setMinimumSize(new Dimension(0, 0));
	filteredPreviewPanel.setMinimumSize(new Dimension(0, 0));
	setPreviewOriginal();
	setPreviewFiltered();
    }

}
